package log

import (
	"fmt"
	"log"
	"strings"
)

const (
	Level_Panic Level = iota // 恐慌错误日志 将抛出一个panic
	Level_Fatal              // 致命错误日志 进程将直接退出
	Level_Error              // 错误日志
	Level_Warn               // 警告日志
	Level_Info               // 一般日志
	Level_Debug              // 调试日志
	Level_Trace              // 追溯日志

	LogKey_Level = "level"
	LogKey_Time  = "time"
	LogKey_File  = "file"
	LogKey_Func  = "func"
	LogKey_Msg   = "msg"
	LogKey_Error = "err"

	LogTimeFormat = "2006/01/02 15:04:05.000"
)

// 当日志数据构建消耗过大时,可以使用闭包将日志数据处理逻辑传递
// 在确定日志可以输出时才构建日志数据,从提高性能
type FunctionLog func() []any

// 自定义字键值对结构
type Fields map[string]any

// 日志等级
type Level uint32

func (lv Level) String() string {
	switch lv {
	case Level_Fatal:
		return "fatal"
	case Level_Panic:
		return "panic"
	case Level_Error:
		return "error"
	case Level_Warn:
		return "warn"
	case Level_Info:
		return "info"
	case Level_Debug:
		return "debug"
	case Level_Trace:
		return "trace"
	}
	return "unknown"
}

// 所有日志等级
var AllLevels = []Level{
	Level_Panic,
	Level_Fatal,
	Level_Error,
	Level_Warn,
	Level_Info,
	Level_Debug,
	Level_Trace,
}

// 解析日志等级
func ParseLevel(str string) (Level, error) {
	switch strings.ToLower(str) {
	case "fatal":
		return Level_Fatal, nil
	case "panic":
		return Level_Panic, nil
	case "error":
		return Level_Error, nil
	case "warn", "warning":
		return Level_Warn, nil
	case "info":
		return Level_Info, nil
	case "debug":
		return Level_Debug, nil
	case "trace":
		return Level_Trace, nil
	}

	var lv Level
	return lv, fmt.Errorf("invalid log level: <%s>", str)
}

// 当log.Logger没有实现StdLogger时不会编译
var (
	_ StdLogger = &log.Logger{}
	_ StdLogger = &Entry{}
	_ StdLogger = &Logger{}
)

// 当前日志库与标准日志库的交集,用于实现当前日志库与标准日志库的通用性
type StdLogger interface {
	Print(...any)
	Printf(string, ...any)
	Println(...any)

	Fatal(...any)
	Fatalf(string, ...any)
	Fatalln(...any)

	Panic(...any)
	Panicf(string, ...any)
	Panicln(...any)
}
